/**
 * Modelisation d'une Cellule, representee par son nom et sa position.
 * Le reste des attributs est decrit dans la classe elle meme.
 */
function Cellule(nom, x, y){
    /*
     * Esperance de vie donnee en tours
     * ecart_vie correspond aux variations de duree de vie permise pour une cellule
     */
    // Declaration des constantes
    /**
     * Appel du constructeur de la classe superieure
     */
    Entite.call(this, nom, x, y);
    /**
     * Array qui permet de connaitre les besoins pour la composition d'une
     * membrane en Molecules
     *
     * @type {Array}
     */
    this.COMPOSITION_MEMBRANE_MOLECULE = [5, 2, 0, 0, 0, 1, 0];
    /**
     * Array qui permet de connaitre les besoins pour la composition d'une
     * membrane en Ccs
     *
     * @type {Array}
     */
    this.COMPOSITION_MEMBRANE_CC = [0, 0, 2, 4, 0];
    /** 
     * Array des Ccs (5 existants). Si l'un des elements n'est pas present,
     * alors on a la valeur 0.
     * Liste des CCs :
     * 		Acetone, Acide sulfurique, Benzene, Eau, Ethanol
     *
     * @type {Array}
     */
    this.COMPOSITION_CC = new Array();
    /**
     * Array de composition en molecules dans l'ordre alphabetique
     * parmi les 7 molecules existantes.
     * Liste des molecules :
     * 		Bretoine, Carottoine, Haricoine, Kiwine, Mongoloine, Oppiomine, Pommine
     *
     * @type {Array}
     */
    this.COMPOSITION_MOLECULE = new Array();
    switch (this.nom) {
        case 'Brasseryte':
            /**
         * Taille de la cellule
         *
         * @type {Number}
         */
            this.TAILLE = 32;
            /**
         * Periode maximale pendant laquelle la cellule peut ne pas se nourrir
         * sans subit de dégâts plus ou moins importants
         *
         * @type {Number}
         */
            this.JEUNE_MAXIMAL = 30;
            /**
         * Determine la capacite de la cellule a resister a la surpopulation
         *
         * @type {Number}
         */
            this.POPULATION_ALENTOUR_MAXIMALE = 4;
            /**
         * Temperature optimale dans laquelle la cellule peut evoluer.
         * Si le monde est a cette temperature plus ou moins l'ecart
         * alors la cellule double sa vitesse
         *
         * @type {Number}
         */
            this.TEMPERATURE_OPTIMALE = 30;
            /**
         * Ecart de temperature qui permet de donner l'interval de
         * temperature pour laquelle la cellule peut doubler sa vitesse
         *
         * @type {Number}
         */
            this.ECART_TEMPERATURE = 1;
            /**
         * Temperature limite minimale pour la cellule a ne pas depasser
         * sans quoi elle subira des degats
         *
         * @type {Number}
         */
            this.TEMPERATURE_MINIMALE = -2;
            /**
         * Temperature limite maximale pour laquelle la cellule subira
         * des degats si la temperature du monde est superieure
         *
         * @type {Number}
         */
            this.TEMPERATURE_MAXIMALE = 50;
            /**
         * Pression optimale pour la survie de la cellule
         *
         * @type {Number}
         */
            this.PRESSION = 1000;
            /**
         * Ecart de pression donnant l'interval que la cellule ne doit
         * pas depasser pour ne pas subir de degats
         *
         * @type {Number}
         */
            this.ECART_PRESSION = 200;
            /**
         * Esperance de vie moyenne de la cellule
         *
         * @type {Number}
         */
            this.ESPERANCE_VIE = 630;
            /**
         * Ecart type moyen de l'esperance de vie de la cellule
         * Ceci fait varier l'age de mort des cellules
         *
         * @type {Number}
         */
            this.ECART_VIE = 150;
            /**
         * Rayon qui permet de determiner a quelle distance une cellule
         * peut appercevoir une source de nourriture autour d'elle
         *
         * @type {Number}
         */
            this.RAYON_RECHERCHE_NOURRITURE = 99;
            /**
         * Composition de la cellule en Molecule
         *
         * @type {Array}
         */
            this.COMPOSITION_MOLECULE = [0, 1, 2, 1, 0, 0, 4];
            /**
         * Composition de la cellule en Ccs
         *
         * @type {Array}
         */
            this.COMPOSITION_CC = [0, 0, 0, 1, 2];
            break;
        case 'Kommyte':
            this.TAILLE = 28;
            this.JEUNE_MAXIMAL = 27;
            this.POPULATION_ALENTOUR_MAXIMALE = 6;
            this.TEMPERATURE_OPTIMALE = 40;
            this.ECART_TEMPERATURE = 2;
            this.TEMPERATURE_MINIMALE = 25;
            this.TEMPERATURE_MAXIMALE = 70;
            this.PRESSION = 950;
            this.ECART_PRESSION = 250;
            this.ESPERANCE_VIE = 580;
            this.ECART_VIE = 80;
            this.RAYON_RECHERCHE_NOURRITURE = 60;
            this.COMPOSITION_MOLECULE = [3, 2, 0, 2, 1, 0, 0];
            this.COMPOSITION_CC = [0, 0, 1, 2, 1];
            break;
        case 'Polakocyte':
            this.TAILLE = 40;
            this.JEUNE_MAXIMAL = 75;
            this.POPULATION_ALENTOUR_MAXIMALE = 2;
            this.TEMPERATURE_OPTIMALE = 15;
            this.ECART_TEMPERATURE = 5;
            this.TEMPERATURE_MINIMALE = -10;
            this.TEMPERATURE_MAXIMALE = 40;
            this.PRESSION = 1150;
            this.ECART_PRESSION = 150;
            this.ESPERANCE_VIE = 1100;
            this.ECART_VIE = 200;
            this.RAYON_RECHERCHE_NOURRITURE = 84;
            this.COMPOSITION_MOLECULE = [3, 0, 0, 0, 18, 2, 0];
            this.COMPOSITION_CC = [0, 1, 0, 1, 0];
            break;
        case 'Samuelocyte':
            this.TAILLE = 20;
            this.JEUNE_MAXIMAL = 21;
            this.POPULATION_ALENTOUR_MAXIMALE = 5;
            this.TEMPERATURE_OPTIMALE = 37;
            this.ECART_TEMPERATURE = 5;
            this.TEMPERATURE_MINIMALE = 5;
            this.TEMPERATURE_MAXIMALE = 50;
            this.PRESSION = 800;
            this.ECART_PRESSION = 250;
            this.ESPERANCE_VIE = 700;
            this.ECART_VIE = 100;
            this.RAYON_RECHERCHE_NOURRITURE = 75;
            this.COMPOSITION_MOLECULE = [3, 1, 1, 3, 0, 0, 0];
            this.COMPOSITION_CC = [1, 4, 0, 0, 0];
            break;
        case 'Zimbabwyte':
            this.TAILLE = 24;
            this.JEUNE_MAXIMAL = 63;
            this.POPULATION_ALENTOUR_MAXIMALE = 3;
            this.TEMPERATURE_OPTIMALE = 70;
            this.ECART_TEMPERATURE = 40;
            this.TEMPERATURE_MINIMALE = 45;
            this.TEMPERATURE_MAXIMALE = 100;
            this.PRESSION = 1200;
            this.ECART_PRESSION = 200;
            this.ESPERANCE_VIE = 600;
            this.ECART_VIE = 200;
            this.RAYON_RECHERCHE_NOURRITURE = 120;
            this.COMPOSITION_MOLECULE = [0, 0, 2, 1, 0, 0, 2];
            this.COMPOSITION_CC = [1, 3, 0, 0, 0];
            break;
        default:
            alert('Cellule inexistante');
            break;
    }
    /**
     * Couleur de la cellule qui reflete son etat de sante
     *
     * @type {String}
     */
    this.couleur;
    /**
     * Age de la cellule
     *
     * @type {Number}
     */
    this.age = 0;
    this.ageMort = this.ESPERANCE_VIE;
    if (Math.random() > 0.5) 
        this.ageMort += Math.round(this.ECART_VIE * Math.random());
    else 
        this.ageMort -= Math.round(this.ECART_VIE * Math.random());
    /**
     * Nombre de tours passés par la cellule sans manger
     *
     * @type{Number}
     */
    this.toursSansManger = 0;
    /**
     * Array qui permet de connaitre le contenu en molecules d'une cellule
     *
     * @type {Array}
     */
    this.contenuMolecule = new Array();
    for (var i = 0; i < 7; i++) {
        this.contenuMolecule.push(Math.floor(this.COMPOSITION_MOLECULE[i] * 0.3 + ((this.COMPOSITION_MOLECULE[i] * 0.7) * Math.random())))
    };
    /**
     * Array qui permet de connaitre le contenu en ccs d'une cellule
     *
     * @type {Array}
     */
    this.contenuCc = new Array();
    for (var i = 0; i < 5; i++) {
        this.contenuCc.push(Math.floor(this.COMPOSITION_CC[i] * 0.3 + ((this.COMPOSITION_CC[i] * 0.7) * Math.random())));
    };
    /**
     * Array qui permet de connaitre les besoins d'une cellule en molecules pour
     * evoluer
     *
     * @type {Array}
     */
    this.besoinMolecule = [0, 0, 0, 0, 0, 0, 0];
    for (var i = 0; i < 7; i++) {
        this.besoinMolecule[i] = Math.round((this.COMPOSITION_MEMBRANE_MOLECULE[i] +
        (this.COMPOSITION_MOLECULE[i] * 2)) *
        1.2) -
        this.contenuMolecule[i];
    };
    /**
     * Array qui permet de connaitre les besoins d'une cellule en cc pour evoluer
     *
     * @type {Array}
     */
    this.besoinCc = [0, 0, 0, 0, 0];
    for (var i = 0; i < 5; i++) {
        this.besoinCc[i] = Math.round((this.COMPOSITION_MEMBRANE_CC[i] +
        (this.COMPOSITION_CC[i] * 2)) *
        1.2) -
        this.contenuCc[i];
    };
    
    /**
     * Methode qui permet de mettre a jour les deux tableaux des besoins de la cellule.
     * Cette methode est appelee lors de la division des cellules afin d'eviter que de
     * la matiere ne se creer spontannement par une mauvaise gestion des besoins.
     */
    this.MaJBesoins = function(){
        for (var i = 0; i < 7; i++) {
            this.besoinMolecule[i] = Math.round((this.COMPOSITION_MEMBRANE_MOLECULE[i] +
            (this.COMPOSITION_MOLECULE[i] * 2)) *
            1.2) -
            this.contenuMolecule[i];
        }
        for (var i = 0; i < 5; i++) {
            this.besoinCc[i] = Math.round((this.COMPOSITION_MEMBRANE_CC[i] +
            (this.COMPOSITION_CC[i] * 2)) *
            1.2) -
            this.contenuCc[i];
        }
    }
    
    /**
     * Methode qui permet de diriger la cellule vers ses besoins les plus urgents,
     * Molecules et Ccs confondus
     *
     * @param {Object} monde Monde de la Cellule
     */
    this.dirigerCellule = function(monde){
        //alert("Contenu Molecules [" + this.contenuMolecule + "]\nContenu Ccs [" + this.contenuCc + "]\n\nBesoins Molecules [" + this.besoinMolecule + "]\nBesoins Ccs [" + this.besoinCc + "]");
        var elimines = 0;
        var chercheMol = [true, true, true, true, true, true, true];
        var chercheCc = [true, true, true, true, true];
        while (elimines < 12) {
            var maxMol = -10000;
            var iMol = -1;
            for (var i = 0; i < 7; i++) {
                if (this.besoinMolecule[i] > maxMol && chercheMol[i] == true) {
                    maxMol = this.besoinMolecule[i];
                    iMol = i;
                }
            };
            var maxCc = -10000;
            var iCc = -1;
            for (var i = 0; i < 5; i++) {
                if (this.besoinCc[i] > maxCc && chercheCc[i] == true) {
                    maxCc = this.besoinCc[i];
                    iCc = i;
                }
            };
            var element;
            if (maxMol >= maxCc) {
                if (iMol != -1) {
                    switch (iMol) {
                        case 0:
                            element = "Bretoine";
                            break;
                        case 1:
                            element = "Carottoine";
                            break;
                        case 2:
                            element = "Haricoine";
                            break;
                        case 3:
                            element = "Kiwine";
                            break;
                        case 4:
                            element = "Mongoloine";
                            break;
                        case 5:
                            element = "Oppiomine";
                            break;
                        case 6:
                            element = "Pommine";
                            break;
                        default:
                            alert("Problème pour iMol");
                            break;
                    }
                    chercheMol[iMol] = false;
                    element = monde.positionBesoinMax(this.x, this.y, this.RAYON_RECHERCHE_NOURRITURE, "Molecule", element);
                }
            }
            else {
                switch (iCc) {
                    case 0:
                        element = "Acetone";
                        break;
                    case 1:
                        element = "Acide sulfurique";
                        break;
                    case 2:
                        element = "Benzene";
                        break;
                    case 3:
                        element = "Eau";
                        break;
                    case 4:
                        element = "Ethanol";
                        break;
                    default:
                        alert("Problème pour iCc");
                        break;
                }
                chercheCc[iCc] = false;
                element = monde.positionBesoinMax(this.x, this.y, this.RAYON_RECHERCHE_NOURRITURE, "Cc", element);
            }
            if (element != null) {
                this.position.changeDestination(element.x, element.y);
                return true;
            }
            if (iMol == -1 || iCc == -1) 
                return false;
            elimines++;
        }
    };
    
    /**
     * Methode qui recupere la position d'un ennemi repere et change au mieux la
     * trajectoire de la cellule pour eviter un conflit
     *
     * @param {Object} monde Monde dans lequel se trouve la cellule
     */
    this.fuirEnnemi = function(monde){
        var ennemi = monde.getEnnemi(this.x, this.y, this.RAYON_RECHERCHE_NOURRITURE);
        if (ennemi != null) 
            this.position.opposee(ennemi.x, ennemi.y);
    };
    
    /**
     * Methode qui permet de redistribuer une partie du contenu de la cellule
     * lorsqu'elle meurt. La fonction modifie le monde en fonction, et supprimer
     * la cellule de celui-ci.
     *
     * @param {Object} monde Monde dans lequel la cellule meurt.
     * @return {Boolean} Retourne vrai si la cellule meurt, faux sinon
     */
    this.rendreLAme = function(monde){
        if (this.age >= this.ageMort) {
            var name = undefined;
            for (var i = 0; i < 7; i++) {
                switch (i) {
                    case 0:
                        name = "Bretoine";
                        break;
                    case 1:
                        name = "Carottoine";
                        break;
                    case 2:
                        name = "Haricoine";
                        break;
                    case 3:
                        name = "Kiwine";
                        break;
                    case 4:
                        name = "Mongoloine";
                        break;
                    case 5:
                        name = "Oppiomine";
                        break;
                    case 6:
                        name = "Pommine";
                        break;
                    default:
                        alert("cellule L353 impossible : " + i);
                        break;
                }
                for (var j = 0; j <
                Math.floor(this.contenuMolecule[i] + this.COMPOSITION_MOLECULE[i] +
                this.COMPOSITION_MEMBRANE_MOLECULE[i]); j++) {
                    if (Math.random() > 0.5) 
                        if (Math.random() > 0.5) 
                            monde.ajouter(name, this.x +
                            Math.round(Math.random() * this.TAILLE), this.y +
                            Math.round(Math.random() * this.TAILLE));
                        else 
                            monde.ajouter(name, this.x +
                            Math.round(Math.random() * this.TAILLE), this.y -
                            Math.round(Math.random() * this.TAILLE));
                    else 
                        if (Math.random() > 0.5) 
                            monde.ajouter(name, this.x -
                            Math.round(Math.random() * this.TAILLE), this.y +
                            Math.round(Math.random() * this.TAILLE));
                        else 
                            monde.ajouter(name, this.x -
                            Math.round(Math.random() * this.TAILLE), this.y -
                            Math.round(Math.random() * this.TAILLE));
                }
            }
            for (var i = 0; i < 5; i++) {
                switch (i) {
                    case 0:
                        name = "Acetone";
                        break;
                    case 1:
                        name = "Acide sulfurique";
                        break;
                    case 2:
                        name = "Benzene";
                        break;
                    case 3:
                        name = "Eau";
                        break;
                    case 4:
                        name = "Ethanol";
                        break;
                    default:
                        alert("cellule L397 impossible : " + i);
                        break;
                }
                for (var j = 0; j <
                Math.floor(this.contenuCc[i] + this.COMPOSITION_CC[i] +
                this.COMPOSITION_MEMBRANE_CC[i]); j++) {
                    if (Math.random() > 0.5) 
                        if (Math.random() > 0.5) 
                            monde.ajouter(name, this.x +
                            Math.round(Math.random() * this.TAILLE), this.y +
                            Math.round(Math.random() * this.TAILLE));
                        else 
                            monde.ajouter(name, this.x +
                            Math.round(Math.random() * this.TAILLE), this.y -
                            Math.round(Math.random() * this.TAILLE));
                    else 
                        if (Math.random() > 0.5) 
                            monde.ajouter(name, this.x -
                            Math.round(Math.random() * this.TAILLE), this.y +
                            Math.round(Math.random() * this.TAILLE));
                        else 
                            monde.ajouter(name, this.x -
                            Math.round(Math.random() * this.TAILLE), this.y -
                            Math.round(Math.random() * this.TAILLE));
                }
            }
            monde.supprimerCellule(this.x, this.y);
            return true;
        }
        else 
            return false;
    };
    
    /**
     * Methode qui tue les cellules en surpopulation s'il y en a.
     *
     * @param {Object} monde Monde dans lequel la cellule evolue
     * @return {Boolean} Vrai si la cellule meurt de surpopulation, faux sinon.
     */
    this.surpopulation = function(monde){
        if (monde.surpeuple(this.nom, this.x, this.y, this.TAILLE, this.POPULATION_ALENTOUR_MAXIMALE)) {
            this.age += this.ageMort;
            this.rendreLAme(monde);
            return true;
        }
        return false;
    };
    
    /**
     * Methode qui permet a la cellule de fabriquer les molecules dont elle a besoin.
     * Elle ne fabriquera pas plus que ses besoins et fabriquera en priorite ce qui
     * lui manque le plus. A l'avenir un besoin energetique pourrait etre introduit,
     * les cellules cherchent donc la nourriture avant d'essayer de la construire.
     */
    this.fabriquerMolecules = function(){
        //TODO : trouver un meilleur moyen d'appeler la methode fabricable de molecule	
        var mol = new Molecule('Haricoine', 0, 0);
        var max = 0;
        var res = new Array();
        var indice = -1;
        var possible = [true, true, true, true, true, true, true];
        var compteur = 7;
        while (compteur > 0) {
            max = 0;
            indice = -1;
            for (var i = 0; i < 7; i++) {
                if (max < this.besoinMolecule[i] && possible[i] == true) {
                    max = this.besoinMolecule[i];
                    indice = i;
                }
            }
            if (indice != -1) {
                res = mol.fabricable(indice, this.contenuCc);
                if (res[5] == true) {
                    for (var i = 0; i < 5; i++) {
                        this.contenuCc[i] -= res[i];
                        this.besoinCc[i] += res[i];
                    }
                    this.besoinMolecule[indice]--;
                    this.contenuMolecule[indice]++;
                }
                else {
                    possible[indice] = false;
                    compteur--;
                }
            }
            else 
                compteur = 0;
        }
    };
    
    /**
     * Methode qui permet a une cellule d'assimiler la nourriture dont elle a besoin
     * et qui se trouve dans le rayon de sa taille.
     *
     * @param {Object} monde Monde de la cellule
     * @return {Boolean} vrai si la cellule s'est nourrie, faux sinon.
     */
    this.assimilerNourriture = function(monde){
        var resultat = false;
        var mols = monde.getNourritureMol(this.x, this.y, this.TAILLE);
        var cyclamides = monde.getNourritureCc(this.x, this.y, this.TAILLE);
        var insere = false;
        if (mols != undefined) {
            for (var i = 0; i < mols.length; i++) {
                switch (mols[i].nom) {
                    case "Bretoine":
                        if ((this.besoinMolecule[0] +
                        this.COMPOSITION_MOLECULE[0] * 2 +
                        this.COMPOSITION_MEMBRANE_MOLECULE[0]) >
                        0) {
                            this.contenuMolecule[0]++;
                            this.besoinMolecule[0]--;
                            insere = true;
                        }
                        break;
                    case "Carottoine":
                        if ((this.besoinMolecule[1] +
                        this.COMPOSITION_MOLECULE[1] * 2 +
                        this.COMPOSITION_MEMBRANE_MOLECULE[1]) >
                        0) {
                            this.contenuMolecule[1]++;
                            this.besoinMolecule[1]--;
                            insere = true;
                        }
                        break;
                    case "Haricoine":
                        if ((this.besoinMolecule[2] +
                        this.COMPOSITION_MOLECULE[2] * 2 +
                        this.COMPOSITION_MEMBRANE_MOLECULE[2]) >
                        0) {
                            this.contenuMolecule[2]++;
                            this.besoinMolecule[2]--;
                            insere = true;
                        }
                        break;
                    case "Kiwine":
                        if ((this.besoinMolecule[3] +
                        this.COMPOSITION_MOLECULE[3] * 2 +
                        this.COMPOSITION_MEMBRANE_MOLECULE[3]) >
                        0) {
                            this.contenuMolecule[3]++;
                            this.besoinMolecule[3]--;
                            insere = true;
                        }
                        break;
                    case "Mongoloine":
                        if ((this.besoinMolecule[4] +
                        this.COMPOSITION_MOLECULE[4] * 2 +
                        this.COMPOSITION_MEMBRANE_MOLECULE[4]) >
                        0) {
                            this.contenuMolecule[4]++;
                            this.besoinMolecule[4]--;
                            insere = true;
                        }
                        break;
                    case "Oppiomine":
                        if ((this.besoinMolecule[5] +
                        this.COMPOSITION_MOLECULE[5] * 2 +
                        this.COMPOSITION_MEMBRANE_MOLECULE[5]) >
                        0) {
                            this.contenuMolecule[5]++;
                            this.besoinMolecule[5]--;
                            insere = true;
                        }
                        break;
                    case "Pommine":
                        if ((this.besoinMolecule[6] +
                        this.COMPOSITION_MOLECULE[6] * 2 +
                        this.COMPOSITION_MEMBRANE_MOLECULE[6]) >
                        0) {
                            this.contenuMolecule[6]++;
                            this.besoinMolecule[6]--;
                            insere = true;
                        }
                        break;
                    default:
                        alert("WTF ? Cellule methode assimilerNourriture")
                }
                if (insere) {
                    resultat = true;
                    monde.supprimerMolecule(mols[i].x, mols[i].y);
                    insere = false;
                }
            }
        }
        if (cyclamides != undefined) {
            for (var i = 0; i < cyclamides.length; i++) {
                switch (cyclamides[i].nom) {
                    case "Acetone":
                        if (this.besoinCc[0] > -8 ||
                        (this.besoinCc[0] +
                        this.COMPOSITION_CC[0] * 5 +
                        this.COMPOSITION_MEMBRANE_CC[0] * 2) >
                        0) {
                            this.contenuCc[0]++;
                            this.besoinCc[0]--;
                            insere = true;
                        }
                        else 
                            if (this.COMPOSITION_CC[0] == 0 &&
                            this.COMPOSITION_MEMBRANE_CC[0] == 0 &&
                            this.besoinCc[0] > -8) {
                                this.contenuCc[0]++;
                                this.besoinCc[0]--;
                                insere = true;
                            }
                        break;
                    case "Acide sulfurique":
                        if (this.besoinCc[1] > -8 ||
                        (this.besoinCc[1] +
                        this.COMPOSITION_CC[1] * 5 +
                        this.COMPOSITION_MEMBRANE_CC[1] * 2) >
                        0) {
                            this.contenuCc[1]++;
                            this.besoinCc[1]--;
                            insere = true;
                        }
                        else 
                            if (this.COMPOSITION_CC[1] == 0 &&
                            this.COMPOSITION_MEMBRANE_CC[1] == 0 &&
                            this.besoinCc[1] > -8) {
                                this.contenuCc[1]++;
                                this.besoinCc[1]--;
                                insere = true;
                            }
                        break;
                    case "Benzene":
                        if (this.besoinCc[2] > -8 ||
                        (this.besoinCc[2] +
                        this.COMPOSITION_CC[2] * 5 +
                        this.COMPOSITION_MEMBRANE_CC[2] * 2) >
                        0) {
                            this.contenuCc[2]++;
                            this.besoinCc[2]--;
                            insere = true;
                        }
                        else 
                            if (this.COMPOSITION_CC[2] == 0 &&
                            this.COMPOSITION_MEMBRANE_CC[2] == 0 &&
                            this.besoinCc[2] > -8) {
                                this.contenuCc[2]++;
                                this.besoinCc[2]--;
                                insere = true;
                            }
                        break;
                    case "Eau":
                        if (this.besoinCc[3] > -8 ||
                        (this.besoinCc[3] +
                        this.COMPOSITION_CC[3] * 5 +
                        this.COMPOSITION_MEMBRANE_CC[3] * 2) >
                        0) {
                            this.contenuCc[3]++;
                            this.besoinCc[3]--;
                            insere = true;
                        }
                        else 
                            if (this.COMPOSITION_CC[3] == 0 &&
                            this.COMPOSITION_MEMBRANE_CC[3] == 0 &&
                            this.besoinCc[3] > -8) {
                                this.contenuCc[3]++;
                                this.besoinCc[3]--;
                                insere = true;
                            }
                        break;
                    case "Ethanol":
                        if (this.besoinCc[4] > -8 ||
                        (this.besoinCc[4] +
                        this.COMPOSITION_CC[4] * 5 +
                        this.COMPOSITION_MEMBRANE_CC[4] * 2) >
                        0) {
                            this.contenuCc[4]++;
                            this.besoinCc[4]--;
                            insere = true;
                        }
                        else 
                            if (this.COMPOSITION_CC[4] == 0 &&
                            this.COMPOSITION_MEMBRANE_CC[4] == 0 &&
                            this.besoinCc[4] > -8) {
                                this.contenuCc[4]++;
                                this.besoinCc[4]--;
                                insere = true;
                            }
                        break;
                    default:
                        alert("WTF ? Cellule methode assimilerNourriture")
                }
                if (insere) {
                    resultat = true;
                    monde.supprimerCc(cyclamides[i].x, cyclamides[i].y);
                    insere = false;
                }
            }
        }
        return resultat;
    };
    
    /**
     * Methode qui permet a une cellule de se diviser si elle en a les moyens
     *
     * @param {Object} monde Monde de la cellule
     * @return {Boolean} Vrai si la cellule peut se diviser, faux sinon.
     */
    this.division = function(monde){
        var possible = true;
        for (var i = 0; i < 7; i++) {
            if (this.besoinMolecule[i] > 0) 
                possible = false;
        }
        for (var i = 0; i < 5; i++) {
            if (this.besoinCc[i] > 0) 
                possible = false;
        }
        //alert("Contenu Molecules [" + this.contenuMolecule + "]\nContenu Ccs [" + this.contenuCc + "]\n\nBesoins Molecules [" + this.besoinMolecule + "]\nBesoins Ccs [" + this.besoinCc + "]");
        if (possible == true) {
            this.diviser(monde);
            return true;
        }
        return false;
    };
    
    /**
     * Methode qui divise une cellule
     *
     * @param {Object} monde Monde de la cellule qui se divise et qui
     * recevra la nouvelle
     */
    this.diviser = function(monde){
        var nom2 = this.nom;
        if (Math.random() < 0.005) {
            //TODO : Remplacer ce truc moche par un switch propre
            var tmp = Math.random();
            if (tmp < 0.2) 
                nom2 = 'Brasseryte';
            else 
                if (tmp < 0.4) 
                    nom2 = 'Kommyte';
                else 
                    if (tmp < 0.6) 
                        nom2 = 'Polakocyte';
                    else 
                        if (tmp < 0.8) 
                            nom2 = 'Samuelocyte';
                        else 
                            if (tmp < 1) 
                                nom2 = 'Zimbabwyte';
            
        }
        var ecartx = Math.round(this.TAILLE * Math.random());
        if (ecartx == 0) 
            ecartx = 1;
        var ecarty = Math.round(this.TAILLE * Math.random());
        if (ecarty == 0) 
            ecarty = 1;
        if (Math.random() > 0.5) {
            if (Math.random() > 0.5) {
                var nouvelleCellule1 = new Cellule(this.nom, this.x + ecartx, this.y + ecarty);
                var nouvelleCellule2 = new Cellule(nom2, this.x - ecartx, this.y - ecarty);
            }
            else {
                var nouvelleCellule1 = new Cellule(this.nom, this.x + ecartx, this.y + ecarty);
                var nouvelleCellule2 = new Cellule(nom2, this.x - ecartx, this.y - ecarty);
            }
        }
        else {
            if (Math.random() > 0.5) {
                var nouvelleCellule1 = new Cellule(this.nom, this.x + ecartx, this.y);
                var nouvelleCellule2 = new Cellule(nom2, this.x - ecartx, this.y);
            }
            else {
                var nouvelleCellule1 = new Cellule(this.nom, this.x, this.y + ecarty);
                var nouvelleCellule2 = new Cellule(nom2, this.x, this.y - ecarty);
            }
        }
        var moitieMolecule = [0, 0, 0, 0, 0, 0, 0];
        for (var i = 0; i < 7; i++) {
            moitieMolecule[i] = Math.round((this.contenuMolecule[i] -
            this.COMPOSITION_MEMBRANE_MOLECULE[i] -
            this.COMPOSITION_MOLECULE[i]) /
            2);
            nouvelleCellule1.contenuMolecule[i] = 0;
            nouvelleCellule1.contenuMolecule[i] += moitieMolecule[i];
            nouvelleCellule2.contenuMolecule[i] = 0;
            nouvelleCellule2.contenuMolecule[i] += this.contenuMolecule[i] - this.COMPOSITION_MEMBRANE_MOLECULE[i] - this.COMPOSITION_MOLECULE[i] - moitieMolecule[i];
        }
        var moitieCc = [0, 0, 0, 0, 0];
        for (var i = 0; i < 5; i++) {
            moitieCc[i] = Math.round((this.contenuCc[i] -
            this.COMPOSITION_MEMBRANE_CC[i] -
            this.COMPOSITION_CC[i]) /
            2);
            nouvelleCellule1.contenuCc[i] = 0;
            nouvelleCellule1.contenuCc[i] += moitieCc[i];
            nouvelleCellule2.contenuCc[i] = 0;
            nouvelleCellule2.contenuCc[i] += this.contenuCc[i] - this.COMPOSITION_MEMBRANE_CC[i] - this.COMPOSITION_CC[i] - moitieCc[i];
        }
        nouvelleCellule1.MaJBesoins();
        nouvelleCellule2.MaJBesoins();
        monde.ajouterCellule(nouvelleCellule1);
        monde.ajouterCellule(nouvelleCellule2);
        monde.supprimerCellule(this.x, this.y);
    };
    
    /**
     * Fonction qui permet de faire manger une cellule si c'est possible et
     * remet le compteur des tours de jeune a 0. Si ce n'est pas possible,
     * alors on incremente le compteur des tours de jeune, et on verifie
     * qu'il n'y ai pas de consequences nefastes.
     *
     * @param {Object} monde Monde de la cellule
     * @return {Boolean} Vrai si la cellule meurt de faim, faux sinon
     */
    this.faim = function(monde){
        if (this.assimilerNourriture(monde) == true) {
            this.toursSansManger = 0;
            return false;
        }
        else {
            this.toursSansManger++;
            if (this.JEUNE_MAXIMAL < this.toursSansManger) 
                if ((this.JEUNE_MAXIMAL * (3 / 2)) > this.toursSansManger) 
                    this.age += 2;
                else 
                    this.age += 4;
            if (this.rendreLAme(monde)) 
                return true;
            else 
                return false;
        }
    };
    
    /**
     * Fonction qui tue les cellules qui ne supportent pas la pression du monde
     *
     * @param {Object} Monde de la cellule
     * @return {true}Vrai si la cellule supporte la pression courante, faux sinon
     */
    this.supportePression = function(monde, pression){
        if (pression > (this.PRESSION + this.ECART_PRESSION) ||
        pression < (this.PRESSION - this.ECART_PRESSION)) {
            this.age += 20;
            if (!this.rendreLAme(monde)) 
                return true;
            else 
                return false;
        }
        return true;
    }
    
    /**
     * Methode qui ajuste la couleur de la cellule selon son etat de sante
     */
    this.ajusteEtatSante = function(){
        var contient = 0;
        var necessaire = 0;
        for (var i = 0; i < 7; i++) {
            contient += this.COMPOSITION_MOLECULE[i] + this.COMPOSITION_MEMBRANE_MOLECULE[i];
        }
        for (var i = 0; i < 5; i++) {
            contient += this.COMPOSITION_CC[i] + this.COMPOSITION_MEMBRANE_CC[i];
        }
        for (var i = 0; i < 7; i++) {
            necessaire += this.contenuMolecule[i];
        }
        for (var i = 0; i < 5; i++) {
            necessaire += this.contenuCc[i];
        }
        if (this.age < (this.ageMort * 25 / 100) &&
        necessaire >= (contient * 70 / 100)) 
            this.couleur = "seagreen";
        else 
            if ((this.age > (this.ageMort * 80 / 100) &&
            necessaire <= (contient * 30 / 100)) ||
            this.age > (this.ageMort * 90 / 100)) 
                this.couleur = "red";
            else 
                if (this.age < (this.ageMort * 1 / 2) &&
                necessaire >= (contient * 1 / 2)) 
                    this.couleur = "lightslategray";
                else 
                    if (this.toursSansManger > this.JEUNE_MAXIMAL) 
                        this.couleur = "orangered";
                    else 
                        this.couleur = "black";
    }
    
    /**
     * Fonction qui tue les cellules qui ne supportent pas la temperature du monde
     *
     * @param {Object} Monde de la cellule
     * @return {true}Vrai si la cellule supporte la temperature courante, faux sinon
     */
    this.supporteTemperature = function(monde, temperature){
        if (temperature > this.TEMPERATURE_MAXIMALE ||
        temperature < this.TEMPERATURE_MINIMALE) {
            this.age += Math.round(Math.random() * 10);
            if (!this.rendreLAme(monde)) {
                this.position.modifierVitesse("normal");
                return true;
            }
            else 
                return false;
        }
        else {
            if (temperature >= this.TEMPERATURE_OPTIMALE - this.ECART_TEMPERATURE &&
            temperature <= this.TEMPERATURE_OPTIMALE + this.ECART_TEMPERATURE) {
                this.position.modifierVitesse("up");
            }
            else {
                this.position.modifierVitesse("normal");
            }
            return true;
        }
        
    }
    
    /**
     * Methode de deplacement qui prend en compte le rayon de recherche de nourriture
     * et la fuite des ennemis
     *
     * @param {Object} monde Monde de la cellule
     */
    this.deplacement = function(monde){
        if (this.nom != 'Polakocyte') 
            this.fuirEnnemi(monde);
        this.position.seDeplace();
        this.x = this.position.getX();
        this.y = this.position.getY();
    };
    
    /**
     * Methode qui permet aux cellules cancereuses d'attaquer les autres
     * cellules. Elles se dirigent vers elle si elles ne sont pas a proximite.
     * L'attaque ne peut avoir lieu qu'au "corps a corps". Si la cellule qui
     * qui applique cette methode n'est pas cancereuse alors il ne se passe
     * rien.
     *
     * @param {Object} monde Monde de la cellule cancereuse
     * @eturn {Boolean} Vrai si this a une cible, faux sinon
     */
    this.attaquer = function(monde){
        var target = monde.getCible(this.x, this.y, this.RAYON_RECHERCHE_NOURRITURE);
        if (target != null) {
            if (target.distance(this.x, this.y) <= this.TAILLE) {
                var degats = 10 + Math.round(15 * Math.random())
                target.age += degats;
                if (target.rendreLAme(monde)) {
                    this.age -= degats;
                }
                else {
                    this.age += 5;
                    this.rendreLAme(monde);
                }
            }
            else 
                this.position.changeDestination(target.x, target.y);
            return true;
        }
        else 
            return false;
    };
    
    /**
     * Methode qui permet a une cellule d'evoluer. Elle verifie les regles de mort et
     * evolution.
     *
     * @return {Boolean} Vrai si la cellule n'est pas morte, faux sinon
     */
    this.evolue = function(monde){
        this.age++;
        if (!this.rendreLAme(monde)) {
            if (!this.faim(monde)) {
                if (!this.surpopulation(monde)) {
                    if (this.nom == "Polakocyte") 
                        var resAttaque = this.attaquer(monde);
                    else 
                        var resAttaque = false;
                    this.fabriquerMolecules();
                    if (!this.division(monde)) {
                        if (resAttaque = false) 
                            this.dirigerCellule(monde);
                        this.deplacement(monde);
                    }
                    return true;
                }
            }
        }
        return false;
    };
}
